library(stringr)
library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.1 ──
✓ ggplot2 3.3.4     ✓ purrr   0.3.4
✓ tibble  3.1.2     ✓ dplyr   1.0.7
✓ tidyr   1.1.3     ✓ forcats 0.5.1
✓ readr   1.4.0     
── Conflicts ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
library(bigrquery)
library(MuMIn)
library(ggplot2)

library(ggpubr)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Registered S3 methods overwritten by 'car':
  method                          from
  influence.merMod                lme4
  cooks.distance.influence.merMod lme4
  dfbeta.influence.merMod         lme4
  dfbetas.influence.merMod        lme4
response <- try(system('~/google-cloud-sdk/bin/gcloud projects list --quiet', intern = T))
projectid <- strsplit(response[2], " ")[[1]][1]

options(na.action = "na.fail") 

source("./helper__dredge_functions.R")
Loading required package: Matrix

Attaching package: ‘Matrix’

The following objects are masked from ‘package:tidyr’:

    expand, pack, unpack


Attaching package: ‘scales’

The following object is masked from ‘package:purrr’:

    discard

The following object is masked from ‘package:readr’:

    col_factor
Trophic Niche Accumulation
accumulation <- read_csv('species_analysis__input__trophic_niche_accumulation.csv')

── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
  trophic_niche = col_character(),
  percent = col_double(),
  merlin_niche_count = col_double(),
  merlin_remaining_species = col_logical(),
  birdlife_niche_count = col_double(),
  birdlife_remaining_species = col_logical()
)
accumulation

birdlife_accumulation = ggplot(accumulation, aes(x = percent, y = birdlife_niche_count)) + 
  geom_line(linetype = "dotted") + 
  geom_line(aes(linetype = birdlife_remaining_species), na.value = "dash") +
  scale_linetype_manual(values=c("blank", "solid"), guide = "none") +
  geom_hline(data = . %>% group_by(trophic_niche) %>% filter(birdlife_niche_count == max(birdlife_niche_count)), aes(yintercept = birdlife_niche_count), color = "blue", size = 0.25, linetype = "dashed") +
  theme_bw() +
  theme(legend.position = "bottom", strip.text = element_text(size = 6), axis.text.x = element_text(angle = 90, size = 6),  axis.text.y = element_text(size = 6)) +
  facet_wrap (~ trophic_niche) +
  xlab("Percentage of all Species") + 
  ylab("Number of Niches") +
  labs(title = "Birdlife Niche Accumulation")
Warning: Ignoring unknown parameters: na.value
birdlife_accumulation

Total number of niches
by_max_birdlife_niche_count = accumulation %>% group_by(trophic_niche) %>% summarise(Value = max(birdlife_niche_count))
by_max_birdlife_niche_count[order(-by_max_birdlife_niche_count$Value),]
ggplot(accumulation, aes(x = percent, y = merlin_niche_count)) + 
  geom_line(linetype = "dotted") + 
  geom_line(aes(linetype = birdlife_remaining_species), na.value = "dash") +
  scale_linetype_manual(values=c("blank", "solid"), guide = "none") +
  geom_hline(data = . %>% group_by(trophic_niche) %>% filter(merlin_niche_count == max(merlin_niche_count)), aes(yintercept = merlin_niche_count), color = "blue", size = 0.25, linetype = "dashed") +
  theme_bw() +
  theme(legend.position = "bottom", strip.text = element_text(size = 6), axis.text.x = element_text(angle = 90, size = 6),  axis.text.y = element_text(size = 6)) +
  facet_wrap (~ factor(trophic_niche, levels = c("Invertivore", "Aquatic predator", "Omnivore", "Vertivore", "Frugivore", "Herbivore aquatic", "Granivore", "Herbivore terrestrial", "Nectarivore", "Scavenger")), scales = "free") +
  xlab("Percentage of Species ranked from the most urbanised") + 
  ylab("Number of Niches") +
  labs(title = "eBird Niche Accumulation") +
  xlim(0, 40)
Warning: Ignoring unknown parameters: na.value
Warning: Removed 12 row(s) containing missing values (geom_path).
Warning: Removed 108 row(s) containing missing values (geom_path).
ggsave("species_analysis__output__trophic_niche_accumlation_merlin.jpg")
Saving 7.29 x 4.51 in image
Warning: Removed 12 row(s) containing missing values (geom_path).
Warning: Removed 108 row(s) containing missing values (geom_path).

ggplot(accumulation, aes(x = percent, y = birdlife_niche_count)) + 
  geom_line(linetype = "dotted") + 
  geom_line(aes(linetype = birdlife_remaining_species), na.value = "dash") +
  scale_linetype_manual(values=c("blank", "solid"), guide = "none") +
  geom_hline(data = . %>% group_by(trophic_niche) %>% filter(birdlife_niche_count == max(birdlife_niche_count)), aes(yintercept = birdlife_niche_count), color = "blue", size = 0.25, linetype = "dashed") +
  theme_bw() +
  theme(legend.position = "bottom", strip.text = element_text(size = 6), axis.text.x = element_text(angle = 90, size = 6),  axis.text.y = element_text(size = 6)) +
  facet_wrap (~ factor(trophic_niche, levels = c("Invertivore", "Aquatic predator", "Omnivore", "Vertivore", "Frugivore", "Herbivore aquatic", "Granivore", "Herbivore terrestrial", "Nectarivore", "Scavenger")), scales = "free") +
  xlab("Percentage of Species ranked from the most urbanised") + 
  ylab("Number of Niches") +
  labs(title = "Birdlife Niche Accumulation") +
  xlim(0, 40)
Warning: Ignoring unknown parameters: na.value
Warning: Removed 12 row(s) containing missing values (geom_path).
Warning: Removed 108 row(s) containing missing values (geom_path).
ggsave("species_analysis__output__trophic_niche_accumlation_birdlife.jpg")
Saving 7.29 x 4.51 in image
Warning: Removed 12 row(s) containing missing values (geom_path).
Warning: Removed 108 row(s) containing missing values (geom_path).

urban_niche_counts <- read_csv("species_analysis__input__birdlife_urban_niche_counts.csv")

── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
  trophic_niche = col_character(),
  urban_niche_count = col_double()
)
urban_niche_counts
Results table for number of urban niches
write_csv(niche_count_data, "species_analysis__output__niche_accumulation_results.csv")
Explore taxonomic families
urbanite_families <- read_csv('species_analysis__input__urbanite_taxonomic_families.csv')

── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
  taxonomic_family = col_character(),
  birdlife_city_count = col_double(),
  birdlife_pool_count = col_double(),
  merlin_city_count = col_double(),
  merlin_pool_count = col_double(),
  birdlife_city_ratio = col_double(),
  merlin_city_ratio = col_double()
)
urbanite_families
nrow(urbanite_families)
[1] 107
families_ordered_by_birdlife <- urbanite_families$taxonomic_family[order(urbanite_families$birdlife_city_ratio)]
urbanite_families$taxonomic_family = factor(urbanite_families$taxonomic_family, levels=families_ordered_by_birdlife)

                  
ggplot(urbanite_families, aes(y = birdlife_city_ratio * 100, x = taxonomic_family)) + 
  geom_point() +
  ylab("Percentage of cities\npresent when in\nregional pool") + xlab("Taxonomic Family") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1, size=5)) 


ggsave("species_analysis__output__birdlife_taxonmic_families.jpg")
Saving 12 x 7.42 in image
families_ordered_by_merlin <- urbanite_families$taxonomic_family[order(urbanite_families$merlin_city_ratio)]
urbanite_families$taxonomic_family = factor(urbanite_families$taxonomic_family, levels=families_ordered_by_merlin)

                  
ggplot(urbanite_families, aes(y = merlin_city_ratio * 100, x = taxonomic_family)) + 
  geom_col( alpha = .2) +
  ylab("") + xlab("") +
  theme_bw() +
  #theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1, size=5)) +
  theme(axis.text.x = element_text(angle = 360/(2*pi) * rev( pi/2 + seq( pi/155, 2*pi-pi/155, len=155)))) +
  theme(panel.border = element_blank(),
        legend.key = element_blank(),
        axis.ticks = element_blank(),
        axis.text.y = element_blank()) +
  coord_polar(clip = "off")
Warning: Vectorized input to `element_text()` is not officially supported.
Results may be unexpected or may change in future versions of ggplot2.
Warning in if (0 <= angle & angle < 90) { :
  the condition has length > 1 and only the first element will be used
Warning in if (0 <= angle & angle < 90) { :
  the condition has length > 1 and only the first element will be used

ggsave("species_analysis__output__merlin_taxonmic_families.jpg")
Saving 12 x 16 in image
Warning in if (0 <= angle & angle < 90) { :
  the condition has length > 1 and only the first element will be used
Warning in if (0 <= angle & angle < 90) { :
  the condition has length > 1 and only the first element will be used
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCmBgYHtyIHNldHVwfQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGJpZ3JxdWVyeSkKbGlicmFyeShNdU1JbikKbGlicmFyeShnZ3Bsb3QyKQoKbGlicmFyeShnZ3B1YnIpCgpyZXNwb25zZSA8LSB0cnkoc3lzdGVtKCd+L2dvb2dsZS1jbG91ZC1zZGsvYmluL2djbG91ZCBwcm9qZWN0cyBsaXN0IC0tcXVpZXQnLCBpbnRlcm4gPSBUKSkKcHJvamVjdGlkIDwtIHN0cnNwbGl0KHJlc3BvbnNlWzJdLCAiICIpW1sxXV1bMV0KCm9wdGlvbnMobmEuYWN0aW9uID0gIm5hLmZhaWwiKSAKCnNvdXJjZSgiLi9oZWxwZXJfX2RyZWRnZV9mdW5jdGlvbnMuUiIpCmBgYAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpUcm9waGljIE5pY2hlIEFjY3VtdWxhdGlvbgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpgYGB7cn0KYWNjdW11bGF0aW9uIDwtIHJlYWRfY3N2KCdzcGVjaWVzX2FuYWx5c2lzX19pbnB1dF9fdHJvcGhpY19uaWNoZV9hY2N1bXVsYXRpb24uY3N2JykKYWNjdW11bGF0aW9uCmBgYApgYGB7cn0KbWVybGluX2FjY3VtdWxhdGlvbiA9IGdncGxvdChhY2N1bXVsYXRpb24sIGFlcyh4ID0gcGVyY2VudCwgeSA9IG1lcmxpbl9uaWNoZV9jb3VudCkpICsgCiAgZ2VvbV9saW5lKGxpbmV0eXBlID0gImRvdHRlZCIpICsgCiAgZ2VvbV9saW5lKGFlcyhsaW5ldHlwZSA9IG1lcmxpbl9yZW1haW5pbmdfc3BlY2llcyksIG5hLnZhbHVlID0gImRhc2giKSArCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcz1jKCJibGFuayIsICJzb2xpZCIpLCBndWlkZSA9ICJub25lIikgKwogIGdlb21faGxpbmUoZGF0YSA9IC4gJT4lIGdyb3VwX2J5KHRyb3BoaWNfbmljaGUpICU+JSBmaWx0ZXIobWVybGluX25pY2hlX2NvdW50ID09IG1heChtZXJsaW5fbmljaGVfY291bnQpKSwgYWVzKHlpbnRlcmNlcHQgPSBtZXJsaW5fbmljaGVfY291bnQpLCBjb2xvciA9ICJibHVlIiwgc2l6ZSA9IDAuMjUsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiksIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHNpemUgPSA2KSwgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSkgKwogIGZhY2V0X3dyYXAgKH4gdHJvcGhpY19uaWNoZSkgKwogIHhsYWIoIlBlcmNlbnRhZ2Ugb2YgYWxsIFNwZWNpZXMiKSArIAogIHlsYWIoIk51bWJlciBvZiBOaWNoZXMiKSArCiAgbGFicyh0aXRsZSA9ICJNZXJsaW4gTmljaGUgQWNjdW11bGF0aW9uIikKCm1lcmxpbl9hY2N1bXVsYXRpb24KYGBgCgoKYGBge3J9CmJpcmRsaWZlX2FjY3VtdWxhdGlvbiA9IGdncGxvdChhY2N1bXVsYXRpb24sIGFlcyh4ID0gcGVyY2VudCwgeSA9IGJpcmRsaWZlX25pY2hlX2NvdW50KSkgKyAKICBnZW9tX2xpbmUobGluZXR5cGUgPSAiZG90dGVkIikgKyAKICBnZW9tX2xpbmUoYWVzKGxpbmV0eXBlID0gYmlyZGxpZmVfcmVtYWluaW5nX3NwZWNpZXMpLCBuYS52YWx1ZSA9ICJkYXNoIikgKwogIHNjYWxlX2xpbmV0eXBlX21hbnVhbCh2YWx1ZXM9YygiYmxhbmsiLCAic29saWQiKSwgZ3VpZGUgPSAibm9uZSIpICsKICBnZW9tX2hsaW5lKGRhdGEgPSAuICU+JSBncm91cF9ieSh0cm9waGljX25pY2hlKSAlPiUgZmlsdGVyKGJpcmRsaWZlX25pY2hlX2NvdW50ID09IG1heChiaXJkbGlmZV9uaWNoZV9jb3VudCkpLCBhZXMoeWludGVyY2VwdCA9IGJpcmRsaWZlX25pY2hlX2NvdW50KSwgY29sb3IgPSAiYmx1ZSIsIHNpemUgPSAwLjI1LCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBzaXplID0gNiksICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gNikpICsKICBmYWNldF93cmFwICh+IHRyb3BoaWNfbmljaGUpICsKICB4bGFiKCJQZXJjZW50YWdlIG9mIGFsbCBTcGVjaWVzIikgKyAKICB5bGFiKCJOdW1iZXIgb2YgTmljaGVzIikgKwogIGxhYnModGl0bGUgPSAiQmlyZGxpZmUgTmljaGUgQWNjdW11bGF0aW9uIikKCmJpcmRsaWZlX2FjY3VtdWxhdGlvbgpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KVG90YWwgbnVtYmVyIG9mIG5pY2hlcwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmBgYHtyfQpieV9tYXhfYmlyZGxpZmVfbmljaGVfY291bnQgPSBhY2N1bXVsYXRpb24gJT4lIGdyb3VwX2J5KHRyb3BoaWNfbmljaGUpICU+JSBzdW1tYXJpc2UoVmFsdWUgPSBtYXgoYmlyZGxpZmVfbmljaGVfY291bnQpKQpieV9tYXhfYmlyZGxpZmVfbmljaGVfY291bnRbb3JkZXIoLWJ5X21heF9iaXJkbGlmZV9uaWNoZV9jb3VudCRWYWx1ZSksXQpgYGAKCmBgYHtyfQpnZ3Bsb3QoYWNjdW11bGF0aW9uLCBhZXMoeCA9IHBlcmNlbnQsIHkgPSBtZXJsaW5fbmljaGVfY291bnQpKSArIAogIGdlb21fbGluZShsaW5ldHlwZSA9ICJkb3R0ZWQiKSArIAogIGdlb21fbGluZShhZXMobGluZXR5cGUgPSBiaXJkbGlmZV9yZW1haW5pbmdfc3BlY2llcyksIG5hLnZhbHVlID0gImRhc2giKSArCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcz1jKCJibGFuayIsICJzb2xpZCIpLCBndWlkZSA9ICJub25lIikgKwogIGdlb21faGxpbmUoZGF0YSA9IC4gJT4lIGdyb3VwX2J5KHRyb3BoaWNfbmljaGUpICU+JSBmaWx0ZXIobWVybGluX25pY2hlX2NvdW50ID09IG1heChtZXJsaW5fbmljaGVfY291bnQpKSwgYWVzKHlpbnRlcmNlcHQgPSBtZXJsaW5fbmljaGVfY291bnQpLCBjb2xvciA9ICJibHVlIiwgc2l6ZSA9IDAuMjUsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiksIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHNpemUgPSA2KSwgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSkgKwogIGZhY2V0X3dyYXAgKH4gZmFjdG9yKHRyb3BoaWNfbmljaGUsIGxldmVscyA9IGMoIkludmVydGl2b3JlIiwgIkFxdWF0aWMgcHJlZGF0b3IiLCAiT21uaXZvcmUiLCAiVmVydGl2b3JlIiwgIkZydWdpdm9yZSIsICJIZXJiaXZvcmUgYXF1YXRpYyIsICJHcmFuaXZvcmUiLCAiSGVyYml2b3JlIHRlcnJlc3RyaWFsIiwgIk5lY3Rhcml2b3JlIiwgIlNjYXZlbmdlciIpKSwgc2NhbGVzID0gImZyZWUiKSArCiAgeGxhYigiUGVyY2VudGFnZSBvZiBTcGVjaWVzIHJhbmtlZCBmcm9tIHRoZSBtb3N0IHVyYmFuaXNlZCIpICsgCiAgeWxhYigiTnVtYmVyIG9mIE5pY2hlcyIpICsKICBsYWJzKHRpdGxlID0gImVCaXJkIE5pY2hlIEFjY3VtdWxhdGlvbiIpICsKICB4bGltKDAsIDQwKQoKCgpnZ3NhdmUoInNwZWNpZXNfYW5hbHlzaXNfX291dHB1dF9fdHJvcGhpY19uaWNoZV9hY2N1bWxhdGlvbl9tZXJsaW4uanBnIikKYGBgCmBgYHtyfQpnZ3Bsb3QoYWNjdW11bGF0aW9uLCBhZXMoeCA9IHBlcmNlbnQsIHkgPSBiaXJkbGlmZV9uaWNoZV9jb3VudCkpICsgCiAgZ2VvbV9saW5lKGxpbmV0eXBlID0gImRvdHRlZCIpICsgCiAgZ2VvbV9saW5lKGFlcyhsaW5ldHlwZSA9IGJpcmRsaWZlX3JlbWFpbmluZ19zcGVjaWVzKSwgbmEudmFsdWUgPSAiZGFzaCIpICsKICBzY2FsZV9saW5ldHlwZV9tYW51YWwodmFsdWVzPWMoImJsYW5rIiwgInNvbGlkIiksIGd1aWRlID0gIm5vbmUiKSArCiAgZ2VvbV9obGluZShkYXRhID0gLiAlPiUgZ3JvdXBfYnkodHJvcGhpY19uaWNoZSkgJT4lIGZpbHRlcihiaXJkbGlmZV9uaWNoZV9jb3VudCA9PSBtYXgoYmlyZGxpZmVfbmljaGVfY291bnQpKSwgYWVzKHlpbnRlcmNlcHQgPSBiaXJkbGlmZV9uaWNoZV9jb3VudCksIGNvbG9yID0gImJsdWUiLCBzaXplID0gMC4yNSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLCBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgc2l6ZSA9IDYpLCAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYpKSArCiAgZmFjZXRfd3JhcCAofiBmYWN0b3IodHJvcGhpY19uaWNoZSwgbGV2ZWxzID0gYygiSW52ZXJ0aXZvcmUiLCAiQXF1YXRpYyBwcmVkYXRvciIsICJPbW5pdm9yZSIsICJWZXJ0aXZvcmUiLCAiRnJ1Z2l2b3JlIiwgIkhlcmJpdm9yZSBhcXVhdGljIiwgIkdyYW5pdm9yZSIsICJIZXJiaXZvcmUgdGVycmVzdHJpYWwiLCAiTmVjdGFyaXZvcmUiLCAiU2NhdmVuZ2VyIikpLCBzY2FsZXMgPSAiZnJlZSIpICsKICB4bGFiKCJQZXJjZW50YWdlIG9mIFNwZWNpZXMgcmFua2VkIGZyb20gdGhlIG1vc3QgdXJiYW5pc2VkIikgKyAKICB5bGFiKCJOdW1iZXIgb2YgTmljaGVzIikgKwogIGxhYnModGl0bGUgPSAiQmlyZGxpZmUgTmljaGUgQWNjdW11bGF0aW9uIikgKwogIHhsaW0oMCwgNDApCgoKCmdnc2F2ZSgic3BlY2llc19hbmFseXNpc19fb3V0cHV0X190cm9waGljX25pY2hlX2FjY3VtbGF0aW9uX2JpcmRsaWZlLmpwZyIpCmBgYAoKCmBgYHtyfQp1cmJhbl9uaWNoZV9jb3VudHMgPC0gcmVhZF9jc3YoInNwZWNpZXNfYW5hbHlzaXNfX2lucHV0X19iaXJkbGlmZV91cmJhbl9uaWNoZV9jb3VudHMuY3N2IikKdXJiYW5fbmljaGVfY291bnRzCmBgYAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClJlc3VsdHMgdGFibGUgZm9yIG51bWJlciBvZiB1cmJhbiBuaWNoZXMKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmBgYHtyfQpiaXJkbGlmZV9jb21wYXJlX2NvdW50cyA8LSBhY2N1bXVsYXRpb25bYWNjdW11bGF0aW9uJHBlcmNlbnQgPT0gMTAwLCBjKCJ0cm9waGljX25pY2hlIiwgImJpcmRsaWZlX25pY2hlX2NvdW50IildCm5hbWVzKGJpcmRsaWZlX2NvbXBhcmVfY291bnRzKSA8LSBjKCJ0cm9waGljX25pY2hlIiwgInRvdGFsX25pY2hlX2NvdW50IikKCmJpcmRsaWZlX2NvbXBhcmVfY291bnRzJHRyb3BoaWNfbmljaGUgPC0gZmFjdG9yKGJpcmRsaWZlX2NvbXBhcmVfY291bnRzJHRyb3BoaWNfbmljaGUpCmJpcmRsaWZlX2NvbXBhcmVfY291bnRzCgpuaWNoZV9jb3VudF9kYXRhIDwtIHJpZ2h0X2pvaW4oYmlyZGxpZmVfY29tcGFyZV9jb3VudHMsIHVyYmFuX25pY2hlX2NvdW50cykKCgpuaWNoZV9jb3VudF9kYXRhJHRvdGFsX3BlcmNlbnRfdXJiYW4gPC0gbmljaGVfY291bnRfZGF0YSR1cmJhbl9uaWNoZV9jb3VudCAvIG5pY2hlX2NvdW50X2RhdGEkdG90YWxfbmljaGVfY291bnQKCm5pY2hlX2NvdW50X2RhdGEKYGBgCgpgYGB7cn0Kd3JpdGVfY3N2KG5pY2hlX2NvdW50X2RhdGEsICJzcGVjaWVzX2FuYWx5c2lzX19vdXRwdXRfX25pY2hlX2FjY3VtdWxhdGlvbl9yZXN1bHRzLmNzdiIpCmBgYAoKCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCkV4cGxvcmUgdGF4b25vbWljIGZhbWlsaWVzCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KYGBge3J9CnVyYmFuaXRlX2ZhbWlsaWVzIDwtIHJlYWRfY3N2KCdzcGVjaWVzX2FuYWx5c2lzX19pbnB1dF9fdXJiYW5pdGVfdGF4b25vbWljX2ZhbWlsaWVzLmNzdicpCnVyYmFuaXRlX2ZhbWlsaWVzCmBgYAoKYGBge3J9Cm5yb3codXJiYW5pdGVfZmFtaWxpZXMpCmBgYAoKYGBge3IsIGZpZy53aWR0aCA9IDZ9CmZhbWlsaWVzX29yZGVyZWRfYnlfYmlyZGxpZmUgPC0gdXJiYW5pdGVfZmFtaWxpZXMkdGF4b25vbWljX2ZhbWlseVtvcmRlcih1cmJhbml0ZV9mYW1pbGllcyRiaXJkbGlmZV9jaXR5X3JhdGlvKV0KdXJiYW5pdGVfZmFtaWxpZXMkdGF4b25vbWljX2ZhbWlseSA9IGZhY3Rvcih1cmJhbml0ZV9mYW1pbGllcyR0YXhvbm9taWNfZmFtaWx5LCBsZXZlbHM9ZmFtaWxpZXNfb3JkZXJlZF9ieV9iaXJkbGlmZSkKCiAgICAgICAgICAgICAgICAgIApnZ3Bsb3QodXJiYW5pdGVfZmFtaWxpZXMsIGFlcyh5ID0gYmlyZGxpZmVfY2l0eV9yYXRpbyAqIDEwMCwgeCA9IHRheG9ub21pY19mYW1pbHkpKSArIAogIGdlb21fcG9pbnQoKSArCiAgeWxhYigiUGVyY2VudGFnZSBvZiBjaXRpZXNcbnByZXNlbnQgd2hlbiBpblxucmVnaW9uYWwgcG9vbCIpICsgeGxhYigiVGF4b25vbWljIEZhbWlseSIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCB2anVzdCA9IDAuNSwgaGp1c3Q9MSwgc2l6ZT01KSkgCgpnZ3NhdmUoInNwZWNpZXNfYW5hbHlzaXNfX291dHB1dF9fYmlyZGxpZmVfdGF4b25taWNfZmFtaWxpZXMuanBnIikKYGBgCmBgYHtyLCBmaWcud2lkdGggPSA2LCBmaWcuaGVpZ2h0ID0gOH0KZmFtaWxpZXNfb3JkZXJlZF9ieV9tZXJsaW4gPC0gdXJiYW5pdGVfZmFtaWxpZXMkdGF4b25vbWljX2ZhbWlseVtvcmRlcih1cmJhbml0ZV9mYW1pbGllcyRtZXJsaW5fY2l0eV9yYXRpbyldCnVyYmFuaXRlX2ZhbWlsaWVzJHRheG9ub21pY19mYW1pbHkgPSBmYWN0b3IodXJiYW5pdGVfZmFtaWxpZXMkdGF4b25vbWljX2ZhbWlseSwgbGV2ZWxzPWZhbWlsaWVzX29yZGVyZWRfYnlfbWVybGluKQoKICAgICAgICAgICAgICAgICAgCmdncGxvdCh1cmJhbml0ZV9mYW1pbGllcywgYWVzKHkgPSBtZXJsaW5fY2l0eV9yYXRpbyAqIDEwMCwgeCA9IHRheG9ub21pY19mYW1pbHkpKSArIAogIGdlb21fY29sKCBhbHBoYSA9IC4yKSArCiAgeWxhYigiIikgKyB4bGFiKCIiKSArCiAgdGhlbWVfYncoKSArCiAgI3RoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdD0xLCBzaXplPTUpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzNjAvKDIqcGkpICogcmV2KCBwaS8yICsgc2VxKCBwaS8xNTUsIDIqcGktcGkvMTU1LCBsZW49MTU1KSkpKSArCiAgdGhlbWUocGFuZWwuYm9yZGVyID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGNvb3JkX3BvbGFyKGNsaXAgPSAib2ZmIikKCmdnc2F2ZSgic3BlY2llc19hbmFseXNpc19fb3V0cHV0X19tZXJsaW5fdGF4b25taWNfZmFtaWxpZXMuanBnIikKYGBgCgoKCg==